package com.itheima.service.Impl;

import com.itheima.mapper.MemberMapper;
import com.itheima.mapper.OrderMapper;
import com.itheima.mapper.SetmealMapper;
import com.itheima.pojo.HotSetmeal;
import com.itheima.service.ReportService;
import com.itheima.vo.BusinessReportVO;
import com.itheima.vo.MemberReportVO;
import com.itheima.vo.SetmealReportVO;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Service
public class ReportServiceImpl implements ReportService {

    @Autowired
    private MemberMapper memberMapper;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private SetmealMapper setmealMapper;

    /**
     * 会员数量统计
     * @return
     */
    public MemberReportVO getMemberReport() {
        MemberReportVO memberReportVO = new MemberReportVO();

        List<LocalDate> months = memberMapper.getAllMonths();

        if (months == null) {
            return null;
        }

        List<String> monthsStr = new ArrayList<>();
        // 使用一个Map来缓存月份和对应的会员数量
        Map<LocalDate, Integer> monthCache = new HashMap<>();

        // 统计当月的会员数量
        List<Integer> memberCounts = new ArrayList<>();
        for (LocalDate month : months) {
            if (month == null) {
                continue; // 跳过 null 的月份
            }
            // 检查缓存中是否已经存在该月份的数据
            if (!monthCache.containsKey(month.withDayOfMonth(month.lengthOfMonth()))) {
                // 如果不存在，则查询数据库并缓存结果
                LocalDate beginDate = month.withDayOfMonth(1);
                LocalDate endDate = month.withDayOfMonth(month.lengthOfMonth());
                Integer memberCount = memberMapper.getMemberCountByDate(beginDate, endDate);
                memberCounts.add(memberCount);
                // 将查询结果缓存起来
                monthCache.put(endDate, memberCount);
                // 将月份添加到列表中
                monthsStr.add(endDate.format(DateTimeFormatter.ofPattern("yyyy.MM.dd")));
            }
        }
        memberReportVO.setMemberCount(memberCounts);

        memberReportVO.setMonths(monthsStr);

        return memberReportVO;
    }

    /**
     * 套餐销售统计
     * @return
     */
    public SetmealReportVO getSetmealReport() {
        // 创建SetmealReportVO对象，用于存储套餐销售报告数据
        SetmealReportVO setmealReportVO = new SetmealReportVO();
    
        // 从订单数据中查询套餐销售数量
        List<Map<String, Object>> setmealCount = orderMapper.findSetmealCount();
    
        // 如果查询结果为空，则返回null
        if (setmealCount == null || setmealCount.isEmpty()){
            return null;
        }
    
        // 提取套餐名称列表
        List<String> setmealNames = new ArrayList<>();
        for (Map<String, Object> map : setmealCount) {
            setmealNames.add((String) map.get("name"));
        }
    
        // 将套餐名称列表和销售统计数据设置到SetmealReportVO对象中
        setmealReportVO.setSetmealNames(setmealNames);
        setmealReportVO.setSetmealCount(setmealCount);
    
        // 返回封装好的SetmealReportVO对象
        return setmealReportVO;
    }

    /**
     * 运营数据统计
     * @return
     */
    public BusinessReportVO getBusinessReportData() {
        BusinessReportVO businessReportVO = new BusinessReportVO();

        // 获取今日到诊人数
        LocalDate beginDate = LocalDate.now();
        LocalDate endDate = LocalDate.now();
        Integer todayVisitsNumber = orderMapper.getMemberCountByDate(beginDate, endDate);
        businessReportVO.setTodayVisitsNumber(todayVisitsNumber);

        // 获取今日新增会员数
        Integer todayNewMember = memberMapper.getMemberCountByDate(beginDate, endDate);
        businessReportVO.setTodayNewMember(todayNewMember);

        // 设置报告日期为今日
        businessReportVO.setReportDate(beginDate);

        // 获取本周到诊人数
        beginDate = LocalDate.now().with(DayOfWeek.MONDAY);
        Integer thisWeekVisitsNumber = orderMapper.getMemberCountByDate(beginDate, endDate);
        businessReportVO.setThisWeekVisitsNumber(thisWeekVisitsNumber);

        // 获取所有套餐的总订单数，并计算热门套餐的占比
        Integer totalSetmealCount = orderMapper.findOrderCountByDate(null,null);
        List<HotSetmeal> hotSetmeals = orderMapper.getHotSetmeal();
        for (HotSetmeal hotSetmeal : hotSetmeals) {
            if(totalSetmealCount == 0){
                break;
            }
            // 四舍五入，保留小数点后两位
            Double proportion = hotSetmeal.getSetmealCount() * 1.0 / totalSetmealCount;
            BigDecimal bd = new BigDecimal(proportion);
            bd = bd.setScale(2, RoundingMode.HALF_UP);
            hotSetmeal.setProportion(bd.doubleValue());
        }
        businessReportVO.setHotSetmeal(hotSetmeals);

        // 获取本月新增会员数
        beginDate = beginDate.withDayOfMonth(1);
        Integer thisMonthNewMember = memberMapper.getMemberCountByDate(beginDate,endDate);
        businessReportVO.setThisMonthNewMember(thisMonthNewMember);

        // 获取本周新增会员数
        beginDate = LocalDate.now().with(DayOfWeek.MONDAY);
        Integer thisWeekNewMember = memberMapper.getMemberCountByDate(beginDate,endDate);
        businessReportVO.setThisWeekNewMember(thisWeekNewMember);

        // 获取总会员数
        Integer totalMember = memberMapper.getMemberCountByDate(null, null);
        businessReportVO.setTotalMember(totalMember);

        // 获取本月订单数
        beginDate = LocalDate.now().withDayOfMonth(1);
        Integer thisMonthOrderNumber = orderMapper.findOrderCountByDate(beginDate, endDate);
        businessReportVO.setThisMonthOrderNumber(thisMonthOrderNumber);

        // 获取本月到诊人数
        Integer thisMonthVisitsNumber = orderMapper.getMemberCountByDate(beginDate, endDate);
        businessReportVO.setThisMonthVisitsNumber(thisMonthVisitsNumber);

        // 获取今日订单数
        beginDate = LocalDate.now();
        Integer todayOrderNumber = orderMapper.findOrderCountByDate(beginDate, endDate);
        businessReportVO.setTodayOrderNumber(todayOrderNumber);

        // 获取本周订单数
        beginDate = LocalDate.now().with(DayOfWeek.MONDAY);
        Integer thisWeekOrderNumber = orderMapper.findOrderCountByDate(beginDate, endDate);
        businessReportVO.setThisWeekOrderNumber(thisWeekOrderNumber);

        return businessReportVO;
    }

    /**
     * 导出运营数据统计
     * @param response
     */
    public void exportBusinessReport(HttpServletResponse response) {

        BusinessReportVO businessReportVO = getBusinessReportData();

        //通过POI将数据写入到Excel文件
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("templates/report_template.xlsx");

        try {
            //基于模板文件创建excel
            XSSFWorkbook excel = new XSSFWorkbook(in);
            //获取sheet页
            XSSFSheet sheet = excel.getSheet("Sheet1");
            //填充时间数据
            sheet.getRow(2).getCell(5).setCellValue(businessReportVO.getReportDate().toString());

            //获得第五行，填充数据
            XSSFRow row = sheet.getRow(4);
            row.getCell(5).setCellValue(businessReportVO.getTodayNewMember());
            row.getCell(7).setCellValue(businessReportVO.getTotalMember());

            //获取第六行，填充数据
            row = sheet.getRow(5);
            row.getCell(5).setCellValue(businessReportVO.getThisWeekNewMember());
            row.getCell(7).setCellValue(businessReportVO.getThisMonthNewMember());

            //获取第八行，填充数据
            row = sheet.getRow(7);
            row.getCell(5).setCellValue(businessReportVO.getTodayOrderNumber());
            row.getCell(7).setCellValue(businessReportVO.getTodayVisitsNumber());

            //获取第九行，填充数据
            row = sheet.getRow(8);
            row.getCell(5).setCellValue(businessReportVO.getThisWeekOrderNumber());
            row.getCell(7).setCellValue(businessReportVO.getThisWeekVisitsNumber());

            //获取第十行，填充数据
            row = sheet.getRow(9);
            row.getCell(5).setCellValue(businessReportVO.getThisMonthOrderNumber());
            row.getCell(7).setCellValue(businessReportVO.getThisMonthVisitsNumber());

            //填充明细数据
            for (int i = 0; i < 4; i++) {
                row = sheet.getRow(i + 12);
                row.getCell(4).setCellValue(businessReportVO.getHotSetmeal().get(i).getName());
                row.getCell(5).setCellValue(businessReportVO.getHotSetmeal().get(i).getSetmealCount());
                row.getCell(6).setCellValue(businessReportVO.getHotSetmeal().get(i).getProportion());
            }

            //设置响应格式为xlsx格式
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");

            //通过输出流将文件下载到客户端
            ServletOutputStream out = response.getOutputStream();
            excel.write(out);

            out.close();
            excel.close();

        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

}
